import { ref } from 'vue'
import { getWsUrl } from '@/utils/config'

// WebSocket连接状态
export const wsStatus = ref('disconnected') // 'connected', 'disconnected', 'connecting', 'error'
export const wsConnected = ref(false)
export const wsError = ref(null)
export const lastMessage = ref(null)

let socket = null
let reconnectTimer = null
let reconnectAttempts = 0
const MAX_RECONNECT_ATTEMPTS = 10
const RECONNECT_INTERVAL = 3000 // 3秒
const PING_INTERVAL = 30000 // 30秒

let pingTimer = null
let wsUrl = ''

// 创建自定义事件
export const wsEvents = new EventTarget()

// 初始化WebSocket
export function initWebSocket(url = getWsUrl()) {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer)
  }
  
  if (pingTimer) {
    clearInterval(pingTimer)
  }
  
  if (socket) {
    closeWebSocket()
  }

  wsStatus.value = 'connecting'
  wsConnected.value = false
  wsError.value = null
  wsUrl = url
  
  try {
    let fullUrl
    
    // Fix for development environment - always use ws://localhost:5000/ws directly
    // instead of letting the browser construct a URL to the frontend server
    if (import.meta.env.DEV && url.startsWith('/')) {
      fullUrl = `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//localhost:5000${url}`
    } else {
      // Production behavior remains unchanged
      fullUrl = url.startsWith('/') 
        ? `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}${url}` 
        : url
    }
    
    socket = new WebSocket(fullUrl)
    
    socket.onopen = () => {
      console.log('WebSocket连接已建立')
      wsStatus.value = 'connected'
      wsConnected.value = true
      reconnectAttempts = 0
      
      // 添加心跳检测
      setupHeartbeat()
      
      // 触发连接事件
      wsEvents.dispatchEvent(new CustomEvent('connected'))
    }
    
    socket.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data)
        lastMessage.value = data
        
        // 触发消息事件
        wsEvents.dispatchEvent(new CustomEvent('message', { detail: data }))
      } catch (error) {
        console.error('解析WebSocket数据失败:', error)
        wsEvents.dispatchEvent(new CustomEvent('error', { 
          detail: { type: 'parse', error, data: event.data } 
        }))
      }
    }
    
    socket.onclose = (event) => {
      console.log('WebSocket连接已关闭:', event.code, event.reason)
      wsStatus.value = 'disconnected'
      wsConnected.value = false
      
      if (pingTimer) {
        clearInterval(pingTimer)
        pingTimer = null
      }
      
      // 触发断开连接事件
      wsEvents.dispatchEvent(new CustomEvent('disconnected', { 
        detail: { code: event.code, reason: event.reason } 
      }))
      
      // 只有非正常关闭时才尝试重连
      if (event.code !== 1000) {
        scheduleReconnect()
      }
    }
    
    socket.onerror = (error) => {
      console.error('WebSocket错误:', error)
      wsStatus.value = 'error'
      wsConnected.value = false
      wsError.value = error
      
      // 触发错误事件
      wsEvents.dispatchEvent(new CustomEvent('error', { detail: error }))
    }
    
    return socket
  } catch (error) {
    console.error('创建WebSocket失败:', error)
    wsStatus.value = 'error'
    wsError.value = error
    scheduleReconnect()
    return null
  }
}

// 设置心跳检测
function setupHeartbeat() {
  if (pingTimer) {
    clearInterval(pingTimer)
  }
  
  pingTimer = setInterval(() => {
    if (socket && socket.readyState === WebSocket.OPEN) {
      try {
        // 发送ping消息
        socket.send(JSON.stringify({ type: 'ping', timestamp: new Date().toISOString() }))
      } catch (error) {
        console.error('发送心跳失败:', error)
        
        // 如果发送失败，关闭连接并重新连接
        closeWebSocket()
        initWebSocket(wsUrl)
      }
    } else if (socket && socket.readyState !== WebSocket.CONNECTING) {
      // 如果连接不是OPEN或CONNECTING状态，重新连接
      closeWebSocket()
      initWebSocket(wsUrl)
    }
  }, PING_INTERVAL)
}

// 关闭WebSocket
export function closeWebSocket() {
  if (socket) {
    try {
      // 先移除所有事件处理器，防止触发onclose事件的重连
      socket.onclose = null
      socket.onerror = null
      socket.onmessage = null
      socket.onopen = null
      
      socket.close(1000, 'Normal closure')
    } catch (error) {
      console.error('关闭WebSocket时发生错误:', error)
    } finally {
      socket = null
    }
  }
  
  if (pingTimer) {
    clearInterval(pingTimer)
    pingTimer = null
  }
  
  wsConnected.value = false
  wsStatus.value = 'disconnected'
}

// 发送数据
export function sendMessage(data) {
  if (!isConnected()) {
    console.error('WebSocket未连接，无法发送数据')
    return false
  }
  
  try {
    socket.send(typeof data === 'string' ? data : JSON.stringify(data))
    return true
  } catch (error) {
    console.error('发送WebSocket数据失败:', error)
    return false
  }
}

// 检查连接状态
export function isConnected() {
  return socket && socket.readyState === WebSocket.OPEN
}

// 获取当前连接状态
export function getConnectionState() {
  if (!socket) return 'CLOSED'
  
  switch(socket.readyState) {
    case WebSocket.CONNECTING: return 'CONNECTING'
    case WebSocket.OPEN: return 'OPEN'
    case WebSocket.CLOSING: return 'CLOSING'
    case WebSocket.CLOSED: return 'CLOSED'
    default: return 'UNKNOWN'
  }
}

// 安排重新连接
function scheduleReconnect() {
  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
    console.log('达到最大重连次数，停止重连')
    wsEvents.dispatchEvent(new CustomEvent('reconnectFailed', {
      detail: { attempts: reconnectAttempts }
    }))
    return
  }
  
  reconnectAttempts++
  const delay = RECONNECT_INTERVAL * Math.pow(1.5, Math.min(reconnectAttempts - 1, 5))
  
  console.log(`${delay/1000}秒后尝试重新连接... (尝试 ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`)
  
  if (reconnectTimer) {
    clearTimeout(reconnectTimer)
  }
  
  reconnectTimer = setTimeout(() => {
    console.log('正在尝试重新连接...')
    wsEvents.dispatchEvent(new CustomEvent('reconnecting', {
      detail: { attempt: reconnectAttempts, maxAttempts: MAX_RECONNECT_ATTEMPTS }
    }))
    initWebSocket(wsUrl)
  }, delay)
}

// 自动重连
export function enableAutoReconnect() {
  window.addEventListener('online', () => {
    console.log('网络已恢复连接，重新连接WebSocket')
    reconnectAttempts = 0
    initWebSocket(wsUrl)
  })
  
  window.addEventListener('focus', () => {
    if (!wsConnected.value && navigator.onLine) {
      console.log('窗口获得焦点，检测到WebSocket断开，尝试重新连接')
      initWebSocket(wsUrl)
    }
  })
}

// 重置重连尝试次数
export function resetReconnectAttempts() {
  reconnectAttempts = 0
} 